﻿namespace TriangleGames.TrainRes
{
    using System;
    using System.Reflection;
    using UnityEngine;

    [Serializable]
    public class FsmProperty
    {
        public FsmBool BoolParameter;
        public FsmFloat FloatParameter;
        public FsmGameObject GameObjectParameter;
        public FsmInt IntParameter;
        public FsmMaterial MaterialParameter;
        private MemberInfo memberInfo;
        public FsmObject ObjectParameter;
        public System.Type prevPropertyType;
        public UnityEngine.Object prevTargetObject;
        public string PropertyName;
        [NonSerialized]
        private string propertyNameCached;
        public System.Type PropertyType;
        public FsmQuaternion QuaternionParameter;
        public FsmRect RectParamater;
        public bool setProperty;
        public FsmString StringParameter;
        public FsmObject TargetObject;
        [NonSerialized]
        private UnityEngine.Object targetObjectCached;
        public System.Type TargetType;
        public string TargetTypeName;
        public FsmTexture TextureParameter;
        public FsmVector3 Vector3Parameter;

        public FsmProperty()
        {
            this.TargetObject = new FsmObject();
            this.TargetTypeName = "";
            this.PropertyName = "";
            this.ResetParameters();
        }

        public FsmProperty(FsmProperty source)
        {
            this.TargetObject = new FsmObject();
            this.TargetTypeName = "";
            this.PropertyName = "";
            this.setProperty = source.setProperty;
            this.TargetObject = new FsmObject(source.TargetObject);
            this.TargetTypeName = source.TargetTypeName;
            this.TargetType = source.TargetType;
            this.PropertyName = source.PropertyName;
            this.PropertyType = source.PropertyType;
            this.BoolParameter = new FsmBool(source.BoolParameter);
            this.FloatParameter = new FsmFloat(source.FloatParameter);
            this.IntParameter = new FsmInt(source.IntParameter);
            this.GameObjectParameter = new FsmGameObject(source.GameObjectParameter);
            this.StringParameter = new FsmString(source.StringParameter);
            this.Vector3Parameter = new FsmVector3(source.Vector3Parameter);
            this.RectParamater = new FsmRect(source.RectParamater);
            this.QuaternionParameter = new FsmQuaternion(source.QuaternionParameter);
            this.ObjectParameter = new FsmObject(source.ObjectParameter);
            this.MaterialParameter = new FsmMaterial(source.MaterialParameter);
            this.TextureParameter = new FsmTexture(source.TextureParameter);
            this.prevPropertyType = source.prevPropertyType;
            this.prevTargetObject = source.prevTargetObject;
        }

        public void GetValue()
        {
            this.Init();
            if (((this.targetObjectCached != null) && (this.memberInfo != null)) && ReflectionUtils.CanReadMemberValue(this.memberInfo))
            {
                System.Type memberUnderlyingType = ReflectionUtils.GetMemberUnderlyingType(this.memberInfo);
                if (memberUnderlyingType.IsAssignableFrom(typeof(bool)))
                {
                    this.BoolParameter.Value = (bool) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(int)))
                {
                    this.IntParameter.Value = (int) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(float)))
                {
                    this.FloatParameter.Value = (float) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(string)))
                {
                    this.StringParameter.Value = (string) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(Vector3)))
                {
                    this.Vector3Parameter.Value = (Vector3) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(Rect)))
                {
                    this.RectParamater.Value = (Rect) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(Quaternion)))
                {
                    this.QuaternionParameter.Value = (Quaternion) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType == typeof(GameObject))
                {
                    this.GameObjectParameter.Value = (GameObject) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType == typeof(Material))
                {
                    this.MaterialParameter.Value = (Material) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType == typeof(Texture))
                {
                    this.TextureParameter.Value = (Texture) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
                else if (memberUnderlyingType.IsSubclassOf(typeof(UnityEngine.Object)))
                {
                    this.ObjectParameter.Value = (UnityEngine.Object) ReflectionUtils.GetMemberValue(this.memberInfo, this.targetObjectCached);
                }
            }
        }

        public void Init()
        {
            if ((this.targetObjectCached != this.TargetObject.Value) || (this.propertyNameCached != this.PropertyName))
            {
                this.targetObjectCached = this.TargetObject.Value;
                this.propertyNameCached = this.PropertyName;
                if ((this.targetObjectCached != null) && !string.IsNullOrEmpty(this.propertyNameCached))
                {
                    System.Type type = this.targetObjectCached.GetType();
                    if (type.GetProperty(this.propertyNameCached) != null)
                        this.memberInfo = type.GetProperty(this.propertyNameCached);
                    else
                        this.memberInfo = type.GetField(this.propertyNameCached);
                    //this.memberInfo = type.GetProperty(this.propertyNameCached) != null ? type.GetProperty(this.propertyNameCached) : type.GetField(this.propertyNameCached);
                    if (this.memberInfo == null)
                    {
                        Debug.LogWarning(string.Concat(new object[] { "Can't find Property or Field: ", this.propertyNameCached, " in: ", this.targetObjectCached, "!" }));
                    }
                    else
                    {
                        this.PropertyType = ReflectionUtils.GetMemberUnderlyingType(this.memberInfo);
                    }
                }
            }
        }

        public void ResetParameters()
        {
            this.BoolParameter = false;
            this.FloatParameter = 0f;
            this.IntParameter = 0;
            this.StringParameter = "";
            this.GameObjectParameter = new FsmGameObject("");
            this.Vector3Parameter = new FsmVector3();
            this.RectParamater = new FsmRect();
            this.QuaternionParameter = new FsmQuaternion();
            this.ObjectParameter = new FsmObject();
            this.MaterialParameter = new FsmMaterial();
            this.TextureParameter = new FsmTexture();
        }

        public void SetPropertyName(string propertyName)
        {
            this.PropertyName = propertyName;
            if (!string.IsNullOrEmpty(this.PropertyName))
            {
                System.Type type = FsmUtility.GetType(this.TargetTypeName);
                if (type != null)
                {
                    PropertyInfo property = type.GetProperty(this.PropertyName);
                    this.PropertyType = (property != null) ? property.PropertyType : null;
                    if (type.IsSubclassOf(typeof(UnityEngine.Object)) && (this.PropertyType != null))
                    {
                        this.ObjectParameter.ObjectType = this.PropertyType;
                    }
                }
            }
            else
            {
                this.PropertyType = null;
            }
        }

        public void SetValue()
        {
            this.Init();
            if (((this.targetObjectCached != null) && (this.memberInfo != null)) && ReflectionUtils.CanSetMemberValue(this.memberInfo))
            {
                System.Type memberUnderlyingType = ReflectionUtils.GetMemberUnderlyingType(this.memberInfo);
                if (memberUnderlyingType.IsAssignableFrom(typeof(bool)) && !this.BoolParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.BoolParameter.Value);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(int)) && !this.IntParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.IntParameter.Value);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(float)) && !this.FloatParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.FloatParameter.Value);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(string)) && !this.StringParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.StringParameter.Value);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(Vector3)) && !this.Vector3Parameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.Vector3Parameter.Value);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(Rect)) && !this.RectParamater.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.RectParamater.Value);
                }
                else if (memberUnderlyingType.IsAssignableFrom(typeof(Quaternion)) && !this.QuaternionParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.QuaternionParameter.Value);
                }
                else if ((memberUnderlyingType == typeof(GameObject)) && !this.GameObjectParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.GameObjectParameter.Value);
                }
                else if ((memberUnderlyingType == typeof(Material)) && !this.MaterialParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.MaterialParameter.Value);
                }
                else if ((memberUnderlyingType == typeof(Texture)) && !this.TextureParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.TextureParameter.Value);
                }
                else if (memberUnderlyingType.IsSubclassOf(typeof(UnityEngine.Object)) && !this.ObjectParameter.IsNone)
                {
                    ReflectionUtils.SetMemberValue(this.memberInfo, this.targetObjectCached, this.ObjectParameter.Value);
                    Debug.Log(this.ObjectParameter.Value);
                }
            }
        }
    }
}

